var fs = require('fs');
var plan = require('./RendezVous.js');
var tools = require('./tools.js');


var keywords = ["BEGIN","VERSION","BEGIN", "DTSTART", "DURATION", "ATTENDEE", "LOCATION", "END"];

var input = [];
var parsedRDV = [];
var rendezVousData = [];

//Ordre DTSTAMP, DTSTART, DURATION, ATTENDEE, LOCATION
exports.fromICal = function fromICal(path){

var data = fs.readFileSync(path, 'utf8');
  
	
	data = unfold(data);
	input = data.split("\n");
	for(var i=0 ; i<input.length; i++){
		input[i] = input[i].split(":");
	}
	calendar();
	
	return parsedRDV;
	
}


//Parse un VCALENDAR
function calendar(){
		expectDefinedData("BEGIN","VCALENDAR");
		expectDefinedData("VERSION","2.0")
		expectEvent();
		expectDefinedData("END","VCALENDAR")
}

//Parse les VEVENT
function expectEvent(){
	//Redondant ?
	if(input[0][0] == "BEGIN" && input[0][1] == "VEVENT"){
		//Nouveau VEVENT---> Nouveau RendezVous
		expectDefinedData("BEGIN","VEVENT");
		expect("DTSTAMP");
		expect("DTSTART");
		expect("DURATION");
		expect("ATTENDEE");
		expect("LOCATION");
		expectDefinedData("END","VEVENT");
		arrayToRDVObject();
		expectEvent();
	}
}

function expect(s){

	var currentLine = next();
	if(currentLine[0] == s){
	//console.log("Trouve : " +s);
		rendezVousData.push(currentLine[1]);
		return true;
	}
	else{
		error(currentLine[0]);
		return false;
	}
}

//S'intéresse aux éléments fixes.
//SKey correspond à la partie gauche des ":", SValue à la partie droite
function expectDefinedData(SKey, SValue){

	var currentLine = next();
		
	if(currentLine[0] == SKey && currentLine[1] == SValue){
		//console.log("Trouve : " + SKey);
		return true;
	}
	else{
		error(currentLine[0]);
		return false;
	}
}

function error(pos){
console.log("Symbole inattendu : "+ pos);
	process.exit(0);
}


function next(){
	if(input.length > 1){
		return input.shift();
	}
	else{
		return input[0];
	}
}
	
	
//Reconstruit les lignes éclatées
function unfold(icalString){

for(var i = 0; i<icalString.length; i++){

	if(icalString.charAt(i) == "\n"){
		if(icalString.charAt(i+1) == " " || icalString.charAt(i+1) == "\t"){
			icalString = icalString.slice(0, i) + icalString.slice(i+2);
		}
	}
}
return icalString;
}

function arrayToRDVObject(){
	
	//Première étape, on subdivise l'évenement en sous-éléments d'une demi-heure
	halfHours = parseDuration(rendezVousData[2]);
	date = parseStart(rendezVousData[1]);
	//Check durée nulle
	if(halfHours && date){
		for(var i=0; i<halfHours; i++){
			var currentRDV = new plan.RendezVous();
			currentRDV.dateIntervention = date[0];
			currentRDV.heureIntervention = tools.ARRAYHOURS[tools.ARRAYHOURS.indexOf(date[1])+i];
			currentRDV.duree = 0.5;
			currentRDV.responsable = rendezVousData[3].trim();
			currentRDV.lieu = rendezVousData[4].trim();
			currentRDV.descCSV = "Missing";
			parsedRDV.push(currentRDV);
		}
		//On vide le tableau une fois traité
		rendezVousData.length = 0 ;
	}
	else{
		console.log("RDV ignoré");
	}
}

//Ignore les secondes, on ne souhaite avoir que des multiples de 30 minutes.
//Retourne la durée en demi-heures
function parseDuration(durationString){
	
	//On veut au moins des minutes ou des heures, pas de jour ni de semaine (on ignore le format des secondes, elles ne seront pas traitées)
	var durationRegExp = /P((([0-9]|1[0-9]|2[0-3])H)?30M|([0-9]|1[0-9]|2[0-3])H(30M)?)([0-9]{1,2}S)?/
	durationString = durationString.trim();
	var correctDuration = durationRegExp.test(durationString);
	if(correctDuration){
		var hours = /([0-9]|1[0-9]|2[0-3])H/.exec(durationString);
		var minutes = /(30)M/.exec(durationString);
		if(hours !== null){
			hours = hours[1];
		}
		else{
			hours = 0;
		}
		if(minutes !== null){
			minutes = 1;
		}
		else{
			minutes=0;
		}
		
		return hours*2+minutes;
	}
	else{
		console.log("Format de durée non géré");
		return false;
	}
}
//On ne traite que les evenements commencant à des demi-heures piles (on ignore les secondes)
function parseStart(startString){
	//Ne regarde pas la cohérence du nombre de jour avec le mois 
	var startRegExp=/([0-9]){4}[0-1][0-2]([0-2][0-9]|3[0-1])T([0-1][0-9]|2[0-3])(00|30)\d\dZ/;
	startString = startString.trim();
	var correctStart = startRegExp.test(startString);
	if(correctStart){
		var dateStart = startString.substr(0,4)+"-"+startString.substr(4,2)+"-"+startString.substr(6,2);
		var hourStart = startString.substr(9,4);
		return [dateStart, hourStart];
	}
	else{
		console.log("Format de date non géré");
		return false;
	}
}



	


